package com.yunzhisec.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.net.DatagramPacket;
import java.net.DatagramSocket;


/**
 * 用于接收syslog事件的监听服务，可以支持udp和tcp两种协议的syslog，具体配置参见eventenginconfig.xml。
 *
 * @author lly
 */
@Component
@Order(10)
@Slf4j
public class SyslogSetupListener implements Runnable, ApplicationRunner {

    public int syslog_port = 514;
    public int syslog_tcp_port = 0;
    public int buffer_size = 8 * 1024;
    public int receive_size = 20000000;
    private byte[] syslogbuffer = new byte[buffer_size];
    private DatagramSocket socket = null;
    private boolean isstarted = false;
   // private EventEnginManager eventmanager = null;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("--------------------------------------syslog监听服务启动开始---------------------------------------");
        this.init();
        log.info("--------------------------------------syslog监听服务启动结束---------------------------------------");
    }

    public void destroy() {
        try {
            isstarted = false;
            Thread.sleep(100);
            if (socket != null) {
                socket.close();
            }
            log.info("Syslog service stop.");
        } catch (Exception e) {
            log.info("Stop syslog service:", e);
        }
        //EventEnginManager.getEventEnginManager().release();
    }

    public void init() {
        // 缓存区大小  20000000  调度容量  60000
        /*System.setProperty("net.sf.cindy.config", Athena.getContextValueAs(String.class, "webinf.dir") + "/conf/event/niolistener.properties");
        eventmanager = EventEnginManager.getEventEnginManager();
        EventEnginConfig eventconfig = EventEnginConfig.getEventEnginConfig();
        Integer port = eventconfig.getInteger("SyslogUDPPort");
        if (port != null) {
            syslog_port = port;
        }

        Integer tcpport = eventconfig.getInteger("SyslogTCPPort");
        if (tcpport != null) {
            syslog_tcp_port = tcpport;
        }

        Integer receivesize = eventconfig.getInteger("SyslogReceiveSize");
        if (receivesize != null) {
            receive_size = receivesize;
        }
*/
        Thread service = new Thread(this);
        service.start();
        log.info("Syslog service start.");
    }

    @Override
    public void run() {
        try {
            // BIO模式
            socket = new DatagramSocket(syslog_port);
            // socket.setReuseAddress(true);
            // DatagramSocket的setReuseAddress(true)方法执行后，可以允许多个DatagramSocket
            // 绑定到相同的IP地址和端口，那么发送到此IP地址和端口的数据能够被复制到多个DatagramSocket
            // 设置socket缓存区大小
            socket.setReceiveBufferSize(receive_size);
            isstarted = true;
        } catch (Exception e) {
            log.info("Start syslog service: port=" + syslog_port, e);
            isstarted = false;
        }

        DatagramPacket syslogdata = new DatagramPacket(syslogbuffer, buffer_size);
        while (isstarted) {
            try {
                socket.receive(syslogdata);
                String source = syslogdata.getAddress().getHostAddress();
                byte[] eventbuffer = new byte[syslogdata.getLength()];
                // 数组复制
                System.arraycopy(syslogdata.getData(), 0, eventbuffer, 0, syslogdata.getLength());
                HandleObject hob = new HandleObject();
                hob.status = HandleObject.STATUS_NOPARSE;
                hob.type = HandleObject.TYPE_CHAR;
                hob.collect = HandleObject.COLLECT_SYSLOG;
                hob.collectip = LocalAddressUtil.getIp();
                hob.sourceip = source;
                hob.contentbyte = eventbuffer;
                //eventmanager.sendEvent(hob);
            } catch (java.io.IOException e) {
            }
            syslogdata.setLength(buffer_size);
        }
    }

}
